﻿using System;
using System.Collections.Generic;
using System.Text;
using MetaView;
using MatrixDataStructures;
using CommonNamespace;

namespace CoregisterDTI
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                System.Diagnostics.Process p = new System.Diagnostics.Process();
                p.StartInfo.FileName = "cmd.exe";
                p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Maximized;
                p.StartInfo.WorkingDirectory = System.IO.Directory.GetCurrentDirectory();
                //p.StartInfo.Arguments = "/k CoregisterDTI.exe";
                p.Start();

                Console.WriteLine("CoregisterDTI.exe DTI.par ANATOMY.par");
                return;
            }
            string dtiParFilename = args[0].ToString();

            Console.WriteLine("Reading DWI file: " + dtiParFilename);
            MetaView.MultipleOptimizedParRecLoader parLoader = new MetaView.MultipleOptimizedParRecLoader(dtiParFilename);
            MatrixDataStructures.MultiVolume diffusionVolume = parLoader.GetData();
            Console.WriteLine("Reading ended.");

            Console.WriteLine("Reading Anatomy file: " + args[1]);
            MetaView.SingleOptimizedParRecLoader anatomyInfo = new SingleOptimizedParRecLoader(args[1]);
            MatrixDataStructures.SingleVolume anatomyVolume = anatomyInfo.GetData();            
            GC.Collect();
            Console.WriteLine("Reading ended.");

            string analyzeFileName = System.IO.Path.GetDirectoryName(dtiParFilename)  + System.IO.Path.GetFileNameWithoutExtension(dtiParFilename);
            System.IO.Directory.CreateDirectory(analyzeFileName + "_raw");

            for (int l = 0; l < diffusionVolume.Matrix.l; l++)
            {
                Console.WriteLine("Writing analyze.. " + analyzeFileName + "_raw\\data_" + l + ".hdr");
                HdrImgWriter.WriteToFile(new MatrixDataStructures.SingleVolume(new Matrix3DInt16(diffusionVolume.Matrix.ExtractVolume(l)), diffusionVolume.FOV, diffusionVolume.Center, null), analyzeFileName + "_raw\\data_" + l );
            }
            Coordinate size = new Coordinate(diffusionVolume.Matrix.i, diffusionVolume.Matrix.j, diffusionVolume.Matrix.k);
            int volumes = diffusionVolume.Matrix.l;

        
            MatrixDataStructures.BasicPixelSizeMatrixInterpolation resampler = new BasicPixelSizeMatrixInterpolation();
            MatrixResizer.MatrixResize resizer = new MatrixResizer.MatrixResize(0); //simple interpolation. should be made a arg[] option later

            # region "Upsampling Parameters"
            CoordinateD anatRes = new CoordinateD(anatomyVolume.FOV.x/ anatomyVolume.Matrix.x, anatomyVolume.FOV.y / anatomyVolume.Matrix.y, anatomyVolume.FOV.z / anatomyVolume.Matrix.z);
            Console.WriteLine("Anatomy Voxel Size: " + anatRes.ToString());
            CoordinateD upsampRes = new CoordinateD(diffusionVolume.FOV.x / anatRes.x, diffusionVolume.FOV.y / anatRes.y, diffusionVolume.FOV.z / anatRes.z);
            Console.WriteLine("Upsampling DTI to:  " + upsampRes.ToString());
            #endregion

            diffusionVolume.Matrix.Dispose();
            GC.Collect();

            GC.AddMemoryPressure(300 * 1024 * 1024);

            System.IO.Directory.CreateDirectory(analyzeFileName + "_iso");
            System.IO.Directory.CreateDirectory(analyzeFileName + "_iso_coreg");
            HdrImgWriter.WriteToFile(new SingleVolume(resampler.ResizePixels(anatomyVolume.Matrix, anatomyVolume.FOV.x, anatomyVolume.FOV.y, anatomyVolume.FOV.z), null, anatomyVolume.FOV, anatomyVolume.Center, anatomyVolume.OffCenterAngle), analyzeFileName + "_iso\\anatomy");
            HdrImgWriter.WriteToFile(new SingleVolume(resampler.ResizePixels(anatomyVolume.Matrix, anatomyVolume.FOV.x, anatomyVolume.FOV.y, anatomyVolume.FOV.z), null, anatomyVolume.FOV, anatomyVolume.Center, anatomyVolume.OffCenterAngle), analyzeFileName + "_iso_coreg\\anatomy");         

            System.IO.Directory.CreateDirectory(analyzeFileName + "_upsamp");
            System.IO.Directory.CreateDirectory(analyzeFileName + "_upsamp_coreg");
            HdrImgWriter.WriteToFile(new SingleVolume(anatomyVolume.Matrix, null, anatomyVolume.FOV, anatomyVolume.Center, anatomyVolume.OffCenterAngle), analyzeFileName + "_upsamp\\anatomy");
            HdrImgWriter.WriteToFile(new SingleVolume(anatomyVolume.Matrix, null, anatomyVolume.FOV, anatomyVolume.Center, anatomyVolume.OffCenterAngle), analyzeFileName + "_upsamp_coreg\\anatomy");         
    
            for (int l = 0; l < volumes; l++)
            {
                Matrix3DInt16 singleVolume = CommonNamespace.HdrImgReader.ReadFromHdrFile(analyzeFileName + "_raw\\data_" + l + ".hdr", HdrImgReader.OutPutType.int16).Matrix;

                Matrix3DInt16 singleVolume_iso = resizer.Resize(singleVolume, diffusionVolume.FOV.x, diffusionVolume.FOV.y, diffusionVolume.FOV.z);
                Matrix3DInt16 singleVolume_upsamp = resizer.Resize(singleVolume,upsampRes.x,upsampRes.y, upsampRes.z);

                Console.WriteLine("Writing analyze.. " + analyzeFileName + "_iso\\data_" + l + ".hdr");
                HdrImgWriter.WriteToFile(new MatrixDataStructures.SingleVolume(singleVolume_iso, diffusionVolume.FOV, diffusionVolume.Center, null), analyzeFileName + "_iso\\data_" + l);
                
                Console.WriteLine("Writing analyze.. " + analyzeFileName + "_upsamp\\data_" + l + ".hdr");
                HdrImgWriter.WriteToFile(new MatrixDataStructures.SingleVolume(singleVolume_upsamp,diffusionVolume.FOV, diffusionVolume.Center, null), analyzeFileName + "_upsamp\\data_" + l);
                
                singleVolume = resampler.ResizeVolumes(singleVolume_iso, diffusionVolume.Center, anatomyVolume.Center, diffusionVolume.FOV, anatomyVolume.FOV);
                Console.WriteLine("Writing analyze.. " + analyzeFileName + "_iso_coreg\\data_" + l + ".hdr");
                HdrImgWriter.WriteToFile(new MatrixDataStructures.SingleVolume(singleVolume, anatomyVolume.FOV, anatomyVolume.Center, null), analyzeFileName + "_iso_coreg\\data_" + l);

                singleVolume = resampler.ResizeVolumes(singleVolume_upsamp, diffusionVolume.Center, anatomyVolume.Center, upsampRes,new CoordinateD(anatomyVolume.Matrix.x, anatomyVolume.Matrix.y, anatomyVolume.Matrix.z));
                Console.WriteLine("Writing analyze.. " + analyzeFileName + "_upsamp_coreg\\data_" + l + ".hdr");
                HdrImgWriter.WriteToFile(new MatrixDataStructures.SingleVolume(singleVolume, anatomyVolume.FOV, anatomyVolume.Center, null), analyzeFileName + "_upsamp_coreg\\data_" + l);

            }
            GC.RemoveMemoryPressure(300 * 1024 * 1024);
            HdrImgWriter.WriteToFile(new SingleVolume(resampler.ResizePixels(anatomyVolume.Matrix, anatomyVolume.FOV.x, anatomyVolume.FOV.y, anatomyVolume.FOV.z),null,anatomyVolume.FOV,anatomyVolume.Center,anatomyVolume.OffCenterAngle), analyzeFileName + "_iso_coreg\\anatomy");         
        }
    }
}